using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.DirectX.DirectDraw;
using System.Drawing;
using Microsoft.DirectX;
using Zsa.Emulation.PPU;

namespace Zsa.Emulation.Render.Video.DirectDraw
{
    /// <summary>
    /// Graphics render that uses direct draw.
    /// </summary>
    public class DirectDrawGraphicRender : GraphicRender
    {
        #region Fields
        /// <summary>
        /// The render device.
        /// </summary>
        private Device _RenderDevice;

        /// <summary>
        /// True if is disposed.
        /// </summary>
        private bool _IsDisposed;

        /// <summary>
        /// The current frame.
        /// </summary>
        private Surface _NameTableImage;

        /// <summary>
        /// The back buffer
        /// </summary>
        private Surface _BackBuffer;

        /// <summary>
        /// The current frame.
        /// </summary>
        private Surface _FrameBuffer;
        
        /// <summary>
        /// The draw area.
        /// </summary>
        private Rectangle _drawLocation;

        /// <summary>
        /// The source rectangle.
        /// </summary>
        private static readonly Rectangle _sourceRectangle = new Rectangle(0, 0, 256, 256);
        #endregion Fields


        #region Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="T:D3dGraphicRender"/> class.
        /// </summary>
        public DirectDrawGraphicRender(DirectDrawRenderSettings settings)
            : base ( settings )
        {

        }
        #endregion Constructor

        #region Methods

        /// <summary>
        /// Initialize the graphic render.
        /// </summary>
        /// <param name="renderSettings"></param>
        protected override void OnUpdateRenderSettings(GraphicRenderSettings renderSettings)
        {
            DirectDrawRenderSettings _SettingsTemp = renderSettings as DirectDrawRenderSettings;
            if (_SettingsTemp == null)
            {
                throw new ArgumentException();
            }


        }
        private DrawEffects effects = new DrawEffects();
        /// <summary>
        /// Draws the frame on to the screen.
        /// </summary>
        public override void DrawScreen()
        {

            LockedData _BitmapData = _NameTableImage.Lock(_sourceRectangle,LockFlags.WriteOnly | LockFlags.DoNotWait);
            base.WriteTable(_BitmapData.Data.InternalData, _BitmapData.Pitch, (byte)(_BitmapData.RGBBitCount/8));
            DrawSprites(_BitmapData.Data.InternalData, _BitmapData.Pitch, (byte)(_BitmapData.RGBBitCount / 8));
            // Unlock the bits.
            _NameTableImage.Unlock(_sourceRectangle);
            _BackBuffer.ColorFill(Ppu.BackgroundColor);
            _BackBuffer.Draw(_drawLocation, _NameTableImage, _sourceRectangle, DrawFlags.KeySource | DrawFlags.DoNotWait, effects);
            _FrameBuffer.Draw(_BackBuffer, DrawFlags.Wait);
        }

        

       


        #region Event Handlers
        /// <summary>
        /// Handles the Resize event of the SurfaceControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
        void SurfaceControl_Resize(object sender, EventArgs e)
        {

        }
        #endregion Event Handlers


        #endregion Methods

        #region Properties
        


        
        #endregion Properties


        protected override void OnDispose()
        {
            if (_RenderDevice != null && !_RenderDevice.Disposed)
            {
                try
                {
                    _RenderDevice.Dispose();
                }
                catch { }
            }
           
        }


        protected override void OnRecreateDevice()
        {
            DirectDrawRenderSettings _SettingsTemp = DeviceSettings as DirectDrawRenderSettings;
            //Create the device.  If device specific use the guid.
            if (_SettingsTemp.IsDeviceSpecific)
            {
                _RenderDevice = new Device(_SettingsTemp.DeviceGuid);
            }
            else // Otherwise use the flags to specify if we require a hardware device.
            {
                _RenderDevice = new Device(_SettingsTemp.CreateFlags);
            }

            // Set the coorperative level.
            _RenderDevice.SetCooperativeLevel(SurfaceControl,
                _SettingsTemp.CooperativeLevelFlags);


            SurfaceDescription description = new SurfaceDescription();
 

            description.Clear();
            description.SurfaceCaps.PrimarySurface = true;
            _FrameBuffer = new Surface(description, _RenderDevice);

            Clipper clipper = new Clipper(_RenderDevice);
            clipper.Window = this._SurfaceControl;
            _FrameBuffer.Clipper = clipper;


            description.Clear();
            description.Width = _FrameBuffer.SurfaceDescription.Width;
            description.Height = _FrameBuffer.SurfaceDescription.Height;
            description.SurfaceCaps.OffScreenPlain = true;

            _BackBuffer = new Surface(description, _RenderDevice);
            _BackBuffer.FillColor = Color.Black;
            

            description.Clear();
            description.Width = 256;
            description.Height = 256;
            description.SurfaceCaps.OffScreenPlain = true;
            _NameTableImage = new Surface(description, _RenderDevice);
            _NameTableImage.SetColorKey(ColorKeyFlags.SourceDraw, new ColorKey() { ColorSpaceHighValue = Color.Pink.ToArgb(), ColorSpaceLowValue = Color.Pink.ToArgb() });

            _drawLocation = _SurfaceControl.RectangleToScreen(new Rectangle(new Point(0, 0), _SurfaceControl.Size));
            // Need subscribe to on move
        }

      
    }


}
